From: Frediano Ziglio Date: Fri, 27 Feb 2015 14:08:06 +0000 (+0000) Subject: xen/arm: Handle translated addresses for hardware domains in GICv2 X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~3695 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https://%22%22/%22http:/www.example.com/cgi/%22https:/%22%22?a=commitdiff_plain;h=5009babad9bfac9c88706e366bed3f2fdf4ed3ca;p=xen.git xen/arm: Handle translated addresses for hardware domains in GICv2 Translated addresses (in d->arch.vgic.{c,d}base) are bus addresses which are not always correct in the context of a subnode in the DTB exposed to domain 0 since they would then be subject to retranslation. Copy the original addresses from DT directly to get the original untranslated reg property which will give same d->arch.vgic.{c,d}base values once translated again by the guest. Signed-off-by: Frediano Ziglio Acked-by: Ian Campbell [ ijc -- attempt to clarify the commit message ] --- diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c index e551549125..3e141c4624 100644 --- a/xen/arch/arm/gic-v2.c +++ b/xen/arch/arm/gic-v2.c @@ -604,7 +604,7 @@ static int gicv2_make_dt_node(const struct domain *d, const struct dt_device_node *gic = dt_interrupt_controller; const void *compatible = NULL; u32 len; - __be32 *new_cells, *tmp; + const __be32 *regs; int res = 0; compatible = dt_get_property(gic, "compatible", &len); @@ -631,18 +631,22 @@ static int gicv2_make_dt_node(const struct domain *d, if ( res ) return res; - len = dt_cells_to_size(dt_n_addr_cells(node) + dt_n_size_cells(node)); - len *= 2; /* GIC has two memory regions: Distributor + CPU interface */ - new_cells = xzalloc_bytes(len); - if ( new_cells == NULL ) - return -FDT_ERR_XEN(ENOMEM); + /* + * DTB provides up to 4 regions to handle virtualization + * (in order GICD, GICC, GICH and GICV interfaces) + * however dom0 just needs GICD and GICC provided by Xen. + */ + regs = dt_get_property(gic, "reg", &len); + if ( !regs ) + { + dprintk(XENLOG_ERR, "Can't find reg property for the gic node\n"); + return -FDT_ERR_XEN(ENOENT); + } - tmp = new_cells; - dt_set_range(&tmp, node, d->arch.vgic.dbase, PAGE_SIZE); - dt_set_range(&tmp, node, d->arch.vgic.cbase, PAGE_SIZE * 2); + len = dt_cells_to_size(dt_n_addr_cells(node) + dt_n_size_cells(node)); + len *= 2; - res = fdt_property(fdt, "reg", new_cells, len); - xfree(new_cells); + res = fdt_property(fdt, "reg", regs, len); return res; }